package com.woniuxy.redis.util;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * redis工具类
 */
@Component
public class RedisUtil {
    /**
     * 连接redis对象
     */
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 自定义redis对象
     */
    @Resource
    private RedisTemplate<String,Object> redisObjectTemplate;

    /**
     * 存储数据
     * @param key 键
     * @param value 值
     */
    public void set(String key,String value){
        stringRedisTemplate.opsForValue().set(key,value);
    }

    /**
     * 存储有过期时间的数据
     * @param key 键
     * @param value 值
     * @param expire 过期实际（以秒为单位）
     */
    public void set(String key,String value,long expire){
        stringRedisTemplate.opsForValue().set(key,value,expire, TimeUnit.SECONDS);
    }

    /**
     * 获取数据
     * @param key 键
     * @return
     */
    public String get(String key){
        String s = stringRedisTemplate.opsForValue().get(key);
        return s;
    }

    /**
     * 判断是否存在某个数据
     * @param key 键
     * @return
     */
    public Boolean hasKey(String key){
        return stringRedisTemplate.hasKey(key);
    }

    /**
     * 对某个数据的值增长
     * @param key 键
     */
    public void insr(String key){
        stringRedisTemplate.opsForValue().increment(key);
        return;
    }

    /**
     * 删除某个数据
     * @param key 键
     */
    public void del(String key){
        stringRedisTemplate.delete(key);
    }

    /**
     * 查询某一个值的排序值
     * @param key
     * @param value
     * @return
     */
    public Double zscore(String key,String value){
        return  stringRedisTemplate.opsForZSet().score(key,value);
    }


    /**
     * 新增zset数据
     * @param key 键
     * @param value 值
     * @param num 排序值
     */
    public void zadd(String key,String value,int num){
        stringRedisTemplate.opsForZSet().add(key,value,num);
    }

    /**
     * 自增数据
     * @param key 键
     * @param value 值
     * @param bank 变化值
     */
    public void zincrby(String key,String value,double bank){
        stringRedisTemplate.opsForZSet().incrementScore(key,value,bank);
    }


    /**
     * 按排序值取数据
     * @param key 键
     * @param start 开始数据位置（包括）
     * @param end 结束数据位置（不包括）
     * @return
     */
    public Set<String> zrevrange(String key,long start,long end){
        Set<String> bookIdStr = stringRedisTemplate.opsForZSet().reverseRange(key, start, end);
        return bookIdStr;
    }

    /**
     * 返回集合中数据个数
     * @param key 键
     * @return
     */
    public Long zcard(String key){
        Long total = stringRedisTemplate.opsForZSet().zCard(key);
        return total;
    }

    /**
     * 删除数据
     * @param key 键
     * @param objects 值
     */
    public void zrem(String key,Object... objects){
        stringRedisTemplate.opsForZSet().remove(key,objects);
    }

    /**
     * 保存数据
     * @param key 键
     * @param map 键值对
     */
    public void hset(String key, Map<String,String> map){
        stringRedisTemplate.opsForHash().putAll(key,map);
    }

    /**
     * 数据自增
     * @param key 键
     * @param value 值
     * @param num 变化值
     */
    public void hincrby(String key,Object value,Integer num){
        stringRedisTemplate.opsForHash().increment(key,value,num);
    }

    /**
     * 获取指定键的所有值
     * @param key 键
     * @return
     */
    public Map<Object,Object> hgetall(String key){
        Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(key);
        return map;
    }

    /**
     * 没有过期时间的reids缓存
     * @param key 键
     * @param value 值
     */
    public void setObject(String key,Object value){
        redisObjectTemplate.opsForValue().set(key,value);
    }

    /**
     * 缓存时间为秒的reids缓存
     * @param key 键
     * @param value 值
     * @param seconds 过期时间
     */
    public void setObject(String key,Object value,long seconds){
        redisObjectTemplate.opsForValue().set(key,value,seconds);
    }

    /**
     * 查看缓存
     * @param key 键
     * @return
     */
    public Object getObject(String key){
        return redisObjectTemplate.opsForValue().get(key);
    }

    /**
     * 按排序值取数据
     * @param key 键
     * @param start 开始数据位置（不包括）
     * @param end 结束数据位置（不包括）
     * @return
     */
    public Set<String> zrange(String key,long start,long end){
        Set<String> strings = stringRedisTemplate.opsForZSet().range(key, start, end);
        return strings;
    }

    /**
     * 通过redisObjectTemplate保存一组以分钟为单位过期的数据
     * @param key 键
     * @param value 值
     * @param minute 过期时间
     */
    public void setObjectExpireMinute(String key,Object value,long minute){
        redisObjectTemplate.opsForValue().set(key, value, minute,TimeUnit.MINUTES);
    }

    /**
     * 为防止缓存击穿，在redisObjectTemplate中存储一组以秒为过期时间的空数据
     * @param key 键
     * @param seconds 过期时间
     */
    public void setNullObjectSecond(String key,long seconds){
        redisObjectTemplate.opsForValue().set(key,null,seconds,TimeUnit.SECONDS);
    }
}
